export default class LinkGame {
  constructor() {
    this.body = document.body;
    this.game = document.querySelector(".game");
    this.temp = "";
    this.len = 10;
    this.gameArr;
    this.controlArr;
    this.firstClick;
    this.secedeClick;
  }
  init() {
    this.renderBack();
    this.bindEvent();
  }
  bindEvent() {
    this.body.addEventListener("click", this.clickEvent.bind(this), false);
  }
  clickEvent(ev) {
    let target = ev.target;
    if (target.tagName === "DIV" && target.className !== "game") {
      let index = +target.getAttribute("data-index");
      let context = target.innerHTML;
      if (context === "") return;
      //this.firstClick !== 0 说明：它是索引可以为0 ，但是第一个判断会是false
      if (!this.firstClick && this.firstClick !== 0) {
        this.firstClick = index;
        this.render(this.firstClick);
      } else {
        if (this.firstClick !== index) {
          this.secedeClick = index;
          this.render(this.secedeClick);
        } else {
          this.render(this.firstClick);
          this.firstClick = undefined;
        }
      }
      // console.log(this.firstClick, this.secedeClick);

      if (this.firstClick >= 0 && this.secedeClick >= 0) {
        let flag = this.remove(this.firstClick, this.secedeClick); //remove() 判断两个点是否满足条件
        if (flag) {
          this.render(this.firstClick, this.secedeClick, true);
          this.firstClick = this.secedeClick = undefined;
        } else {
          this.render(this.firstClick);
          this.firstClick = this.secedeClick;
          this.secedeClick = undefined;
        }
        // console.log(this.firstClick, this.secedeClick);
      }
    }
  }
  render(fIndex, sIndex, flag) {
    fIndex !== undefined &&
      this.game.children[fIndex].classList.toggle("shadow");
    sIndex !== undefined &&
      this.game.children[sIndex].classList.toggle("shadow");
    if (flag)
      this.game.children[fIndex].innerHTML = this.game.children[
        sIndex
      ].innerHTML = "";
  }

  renderBack() {
    this.creatGameArr();
    let s = this.len ** 2;
    for (let i = 0; i < s; i++) {
      this.temp += `<div data-index=${i}>${this.gameArr[i]}</div>`;
    }
    this.game.innerHTML = this.temp;
  }
  creatGameArr() {
    this.gameArr = Array.from(
      { length: this.len ** 2 },
      (item, index) => ~~(index / 10) || 1
      //短路运算 把0替换为1，因为后面0代表着空
    ).sort(() => Math.random() - 0.5);
    this.controlArr = Array.from(
      { length: this.len + 2 },
      (rowArr, rowIndex) =>
        (rowArr = Array.from({ length: this.len + 2 }, (colItem, colIndex) => {
          let flag =
            rowIndex === 0 ||
            rowIndex === this.len + 1 ||
            colIndex === 0 ||
            colIndex === this.len + 1;
          if (flag) {
            return 0;
          } else {
            let index = (rowIndex - 1) * this.len + colIndex - 1;
            return this.gameArr[index];
          }
        }))
    );
  }
  remove(first, secend) {
    let fx = ~~(first / this.len) + 1,
      fy = (first % this.len) + 1;
    let sx = ~~(secend / this.len) + 1,
      sy = (secend % this.len) + 1;
    let isSame = this.controlArr[fx][fy] === this.controlArr[sx][sy];
    if (!isSame) return false;
    let isOk = false;
    let res;
    if (fx === sx && !isOk) {
      res = this.horizon(fx, fy, sy);
      isOk = res.length !== 0;
    }
    if (fy === sy && !isOk) {
      res = this.vertical(fx, sx, fy);
      isOk = res.length !== 0;
    }
    if (!isOk) {
      res = this.onceTurn(fx, fy, sx, sy);
      isOk = res.length !== 0;
    }
    if (!isOk) {
      res = this.twiceTurn(fx, fy, sx, sy);
      isOk = res.length !== 0;
    }
    if (!isOk) {
      res = this.twiceTurn(sx, sy, fx, fy);
      isOk = res.length !== 0;
    }
    // console.log(res);
    // console.log(this.controlArr);
    isOk && this.changeControlArr(fx, fy, sx, sy) && this.drawLine(res);

    return isOk;
  }
  // 是空的
  isVoid(x, y) {
    return (
      x >= 0 &&
      x <= this.len + 1 &&
      y >= 0 &&
      y <= this.len + 1 &&
      this.controlArr[x][y] === 0
    );
  }
  //成功后改变二维数组
  changeControlArr(fx, fy, sx, sy) {
    this.controlArr[fx][fy] = this.controlArr[sx][sy] = 0;
    return true; // 让上面继续短路运算 改变二维数组和画线
  }
  //横向 fx===sx //flag为false 方法被借用
  horizon(x, fy, sy, flag = true) {
    let start = Math.min(fy, sy),
      end = Math.max(fy, sy);
    for (let i = start + 1; i < end; i++) {
      if (this.controlArr[x][i] !== 0) {
        return [];
      }
    }
    return [
      { x, y: fy },
      { x, y: sy },
    ];
  }
  //竖向 fy===sy //flag为false 方法被借用
  vertical(fx, sx, y, flag = true) {
    let start = Math.min(fx, sx),
      end = Math.max(fx, sx);
    for (let i = start + 1; i < end; i++) {
      if (this.controlArr[i][y] !== 0) {
        return [];
      }
    }
    return [
      { x: fx, y },
      { x: sx, y },
    ];
  }
  //转一次弯
  onceTurn(fx, fy, sx, sy) {
    // console.log(fx, fy, sx, sy);
    let isOk = false;
    let mx, my;
    if (this.isVoid(sx, fy)) {
      isOk =
        this.vertical(fx, sx, fy).length !== 0 &&
        this.horizon(sx, fy, sy).length !== 0;
      if (isOk) {
        mx = sx;
        my = fy;
      }
    } else if (this.isVoid(fx, sy) && !isOk) {
      isOk =
        this.horizon(fx, fy, sy).length !== 0 &&
        this.vertical(fx, sx, sy).length !== 0;
      if (isOk) {
        mx = fx;
        my = sy;
      }
    }

    return isOk
      ? [
          { x: fx, y: fy },
          { x: mx, y: my },
          { x: sx, y: sy },
        ]
      : [];
  }
  //转两次弯 遍历找到满足第一个点横向或竖向检测的点 ，再进行一次转弯检测
  twiceTurn(fx, fy, sx, sy) {
    let res = this.check(fx, 0, fy, -1, sx, sy);
    if (res.length === 0) res = this.check(fx, 0, fy, 1, sx, sy);
    if (res.length === 0) res = this.check(fx, -1, fy, 0, sx, sy);
    if (res.length === 0) res = this.check(fx, 1, fy, 0, sx, sy);
    //因为 只检测行和列 十字
    // console.log(res);
    return res.length === 0 ? [] : [{ x: fx, y: fy }, ...res];
  }
  check(fx, xdirection, fy, ydirection, sx, sy) {
    fx += xdirection;
    fy += ydirection;
    let res = [];
    if (this.isVoid(fx, fy)) {
      res = this.onceTurn(fx, fy, sx, sy);
      if (res.length === 0) {
        res = this.check(fx, xdirection, fy, ydirection, sx, sy);
      }
    }
    return res;
  }
  drawLine(arg) {
    let tempt = document.createDocumentFragment();
    for (let i = 1; i < arg.length; i++) {
      let span = document.createElement("span");
      let width, height;
      //同行
      if (arg[i].x === arg[i - 1].x) {
        width = `${Math.abs(arg[i].y - arg[i - 1].y) * 60}px`;
        height = "4px";
      } else if (arg[i].y === arg[i - 1].y) {
        width = "4px";
        height = `${Math.abs(arg[i].x - arg[i - 1].x) * 60}px`;
      }
      let left = `${-30 + Math.min(arg[i].y, arg[i - 1].y) * 60}px`;
      let top = `${-30 + Math.min(arg[i].x, arg[i - 1].x) * 60}px`;

      span.style.width = width;
      span.style.height = height;
      span.style.left = left;
      span.style.top = top;
      tempt.appendChild(span);
    }
    let len = arg.length - 1;
    //添加线
    this.game.appendChild(tempt);
    //删除线
    setTimeout(() => {
      for (let i = 0; i < len; i++) {
        this.game.removeChild(
          this.game.children[this.game.children.length - 1]
        );
      }
    }, 100);
  }
}
/*     for (let i = fx - 1; i >= 0; i--) {
      if (this.controlArr[i][fy] === 0) {
        res = this.onceTurn(i, fy, sx, sy);
        isOk = res.length !== 0;
        if (!isOk) {
          continue;
        } else {
          console.log(1);
          return [{ x: fx, y: fy }, ...res];
        }
      } else {
        break;
      }
    }
    for (let i = fx + 1; i <= this.len + 1; i++) {
      if (this.controlArr[i][fy] === 0) {
        res = this.onceTurn(i, fy, sx, sy);
        isOk = res.length !== 0;
        if (!isOk) {
          continue;
        } else {
          console.log(1);
          return [{ x: fx, y: fy }, ...res];
        }
      } else {
        break;
      }
    }
    for (let i = fy - 1; i >= 0; i--) {
      if (this.controlArr[fx][i] === 0) {
        res = this.onceTurn(fx, i, sx, sy);
        isOk = res.length !== 0;
        if (!isOk) {
          continue;
        } else {
          console.log(1);
          return [{ x: fx, y: fy }, ...res];
        }
      } else {
        break;
      }
    }
    for (let i = fy + 1; i <= this.len + 1; i++) {
      if (this.controlArr[fx][i] === 0) {
        res = this.onceTurn(fx, i, sx, sy);
        isOk = res.length !== 0;
        if (!isOk) {
          continue;
        } else {
          console.log(1);
          return [{ x: fx, y: fy }, ...res];
        }
      } else {
        break;
      }
    }
    return []; */
